package com.zztl.infiniteBand.ui.view

import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Point
import android.os.Handler
import android.os.Message
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.animation.Animation
import android.view.animation.AnimationUtils
import android.view.animation.LinearInterpolator
import android.widget.FrameLayout
import android.widget.TextView
import com.zztl.infiniteBand.R
import com.zztl.infiniteBand.model.Position
import com.zztl.infiniteBand.util.DataFormatUtil
import java.text.NumberFormat
import java.util.*
import kotlin.collections.ArrayList

/**

 * 描述:
 * 处理思路：
 * ->将森林水滴作为一个总体而不是单个的view，自定义一个ViewGroup容器
 * ->循环创建view
 * ->为view随机设置位置(在一些固定的集合中随机选取，尽量保证水滴不重合)
 * ->为view设置一个初始的运动方向（注：由于每个view的运动方向不同，所以我选择将方向绑定到view的tag中）
 * ->为view设置一个初始的速度（同理：将初始速度绑定到view的tag中）
 * ->添加view到容器中，并缩放伴随透明度显示
 * ->开启handler达到view上下位移动画（注意点：这里我们需要定一个临界值来改变view的速度，到达view时而快时而慢的目的）
 * ->点击view后，缩放、透明度伴随位移移除水滴
 * ->界面销毁时停止调用handler避免内存泄漏，空指针等异常
 */
class DiamondView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : FrameLayout(context, attrs, defStyleAttr) {
    /**
     * 控制水滴动画的快慢
     */
    private val mSpds = Arrays.asList(0.5f, 0.3f, 0.2f, 0.1f)
    //    private static final List<Float> Y_MAX_CHOSE_RANDOMS = new ArrayList<>();
    /**
     * x坐标当前可选的随机数组
     */
    private val mXCurrentCanShoseRandoms = ArrayList<Float>()
    /**
     * y坐标当前可选的随机数组
     */
    private val mYCurrentCanShoseRandoms = ArrayList<Float>()

    /**
     * 已经选取x的随机数值
     */
    private val mXRandoms = ArrayList<Float>()
    /**
     * 已经选取y的随机数值
     */
    private val mYRandoms = ArrayList<Float>()


    private val mRandom = Random()
    private val mViews = ArrayList<View>()
    private val mChildViewRes = R.layout.item_diamond//子view的资源文件

    private val mInflater: LayoutInflater
    private val mTotalConsumeWater: Int = 0//总的已经点击的水滴
    private var isOpenAnimtion: Boolean = false//是否开启动画
    private var isCancelAnimtion: Boolean = false//是否销毁动画
    private var maxX: Int = 0
    private var maxY: Int = 0//子view的x坐标和y坐标的最大取值
    private var mMaxSpace: Float = 0.toFloat()//父控件对角线的距离
    private var mDestroyPoint: Point? = null//view销毁时的点
    //    private TranslateAnimation mAnimation;
    private var mEndListener: AnimatorEndListener? = null
    private var mXNum: Int = 0
    private var mYNum: Int = 0
    private val childView: View
    private var mXPercent: Float? = null
    private var mYPercent: Float? = null
    private var clickListener: ClickListener? = null
    private var mAnimation: Animation? = null

    @SuppressLint("HandlerLeak")
    private val mHandler = object : Handler() {
        override fun handleMessage(msg: Message) {
            //根据isCancelAnimtion来标识是否退出，防止界面销毁时，再一次改变UI
            if (isCancelAnimtion) {
                return
            }
            setOffSet()
            this.sendEmptyMessageDelayed(WHAT_ADD_PROGRESS, PROGRESS_DELAY_MILLIS.toLong())
        }
    }

    val viewsSize: Int
        get() = mViews.size

    val views: ArrayList<View>
        get() = mViews

    init {
        mInflater = LayoutInflater.from(getContext())
        childView = mInflater.inflate(mChildViewRes, this, false)

    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        mMaxSpace = Math.sqrt((w * w + h * h).toDouble()).toFloat()
        mDestroyPoint = Point(x.toInt(), h)
        maxX = w
        maxY = h
        childView.measure(0, 0)
        val childW = childView.measuredWidth
        val childH = childView.measuredHeight
    /*    mXPercent = java.lang.Float.valueOf(getnum(childW, maxX))
        mYPercent = java.lang.Float.valueOf(getnum(childH, maxY))
        Log.i("swl", "mXPercent---------------$mXPercent-------------$mYPercent")*/
        mXNum = maxX / childW
        mYNum = maxY / childH
    }

    /**
     * 界面销毁时回调
     */
    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        onDestroy()
    }

    /**
     * 重置子view
     */
    private fun reset() {
        isCancelAnimtion = true
        isOpenAnimtion = false
        for (i in mViews.indices) {
            removeView(mViews[i])
        }
        mViews.clear()
        mXRandoms.clear()
        mYRandoms.clear()
        mYCurrentCanShoseRandoms.clear()
        mXCurrentCanShoseRandoms.clear()
        X_Y_CHOSE_RANDOMS.clear()
        clearAnimation()
        mHandler.removeCallbacksAndMessages(null)
    }

    /**
     * 设置水滴
     *
     * @param waters
     */
    fun setWaters(waters: List<Diamond>?) {
        if (waters == null || waters.isEmpty()) {
            reset()
            return
        }
        //确保初始化完成
        post { setDatas(waters) }
    }

    /**
     * 设置数据
     *
     * @param waters
     */
    private fun setDatas(waters: List<Diamond>?) {
        reset()
        isCancelAnimtion = false
        setCurrentCanChoseRandoms()
        addWaterView(waters!!)
        setViewsSpd()
        startAnimation()
        mEndListener?.finishAddView()

    }


    private fun setCurrentCanChoseRandoms() {
        //        X_Y_CHOSE_RANDOMS.add(new Position(0.01f, 0.35f));
        X_Y_CHOSE_RANDOMS.add(Position(0.62f, 0.13f))
        X_Y_CHOSE_RANDOMS.add(Position(0.22f, 0.45f))
        X_Y_CHOSE_RANDOMS.add(Position(0.02f, 0.37f))
        X_Y_CHOSE_RANDOMS.add(Position(0.21f, 0.11f))
        X_Y_CHOSE_RANDOMS.add(Position(0.38f, 0.01f))  //中间
        X_Y_CHOSE_RANDOMS.add(Position(0.42f, 0.36f))
        X_Y_CHOSE_RANDOMS.add(Position(0.595f, 0.45f))
        X_Y_CHOSE_RANDOMS.add(Position(0.76f, 0.37f))
        X_Y_CHOSE_RANDOMS.add(Position(0.73f, 0.75f))
        X_Y_CHOSE_RANDOMS.add(Position(0.2f, 0.73f))
        //        X_Y_CHOSE_RANDOMS.add(new Position(0.85f, 0.35f));

    }

    private fun addWaterView(waters: List<Diamond>) {

        for (i in waters.indices) {
            val water = waters[i]
            val view = mInflater.inflate(mChildViewRes, this, false)
            val tvWater = view.findViewById<TextView>(R.id.tv_diamong)
            view.tag = water
            tvWater.text = DataFormatUtil.converTxtPoint4(water.number)
            view.setOnClickListener { _ -> handViewClick(view) }

            setChildViewLocation(view)
            mViews.add(view)
            addShowViewAnimation(view)
        }
    }

    fun getnum(num1: Int, num2: Int): String {
        val numberFormat = NumberFormat.getInstance()
        // 设置精确到小数点后2位
        numberFormat.maximumFractionDigits = 2
        return numberFormat.format((java.lang.Float.valueOf(num1.toFloat())!! / java.lang.Float.valueOf(num2.toFloat())!!).toDouble())
    }


    /**
     * 添加显示动画
     *
     * @param view
     */
    private fun addShowViewAnimation(view: View) {
        addView(view)
        view.alpha = 0f
        view.scaleX = 0f
        view.scaleY = 0f
        view.animate().alpha(1f).scaleX(1f).scaleY(1f).setDuration(ANIMATION_SHOW_VIEW_DURATION.toLong()).start()
    }

    /**
     * 处理view点击
     *
     * @param view
     */
    private fun handViewClick(view: View) {
        //移除当前集合中的该view
//        mViews.remove(view)
        if (null != clickListener) {
            clickListener!!.clickItem(view)
        }

    }

    /**
     * 设置view在父控件中的位置
     *
     * @param view
     */
    private fun setChildViewLocation(view: View) {
        val x_yRandom = getX_YRandom(X_Y_CHOSE_RANDOMS)
        view.x = maxX * x_yRandom.x
        view.y = maxY * x_yRandom.y
        view.setTag(R.string.original_y, view.y)
    }

    /*   */

    /**
     * 获取x轴或是y轴上的随机值
     *
     * @return
     *//*
    private double getX_YRandom(List<Float> choseRandoms, List<Float> saveRandoms) {

        if (choseRandoms.size() <= 0) {
            //防止水滴别可选项的个数还要多，这里就重新对可选项赋值
            setCurrentCanChoseRandoms();
        }
        //取用一个随机数，就移除一个随机数，达到不用循环遍历来确保获取不一样的值
        float random = choseRandoms.get(mRandom.nextInt(choseRandoms.size()));
        choseRandoms.remove(random);
        saveRandoms.add(random);
        return random;
    }*/
    private fun getX_YRandom(choseRandoms: MutableList<Position>): Position {

        if (choseRandoms.size <= 0) {
            //防止水滴别可选项的个数还要多，这里就重新对可选项赋值
            setCurrentCanChoseRandoms()
        }
        //取用一个随机数，就移除一个随机数，达到不用循环遍历来确保获取不一样的值
        val position = choseRandoms[mRandom.nextInt(choseRandoms.size)]
        choseRandoms.remove(position)
        //        saveRandoms.add(position);
        return position
    }

    /**
     * 设置所有子view的加速度
     */
    private fun setViewsSpd() {
        for (i in mViews.indices) {
            val view = mViews[i]
            setSpd(view)
        }
    }

    /**
     * 设置View的spd
     *
     * @param view
     */
    private fun setSpd(view: View) {
        val spd = mSpds[mRandom.nextInt(mSpds.size)]
        view.setTag(R.string.spd, spd)
    }

    /**
     * 设置偏移
     */
    private fun setOffSet() {

        mAnimation = AnimationUtils.loadAnimation(context, R.anim.scale_diamond_animation)
        this.animation = mAnimation
        mAnimation!!.start()
    }


    /**
     * 获取两个点之间的距离
     *
     * @param p1
     * @param p2
     * @return
     */
    fun getDistance(p1: Point, p2: Point): Float {
        val _x = Math.abs(p2.x - p1.x).toFloat()
        val _y = Math.abs(p2.y - p1.y).toFloat()
        return Math.sqrt((_x * _x + _y * _y).toDouble()).toFloat()
    }

    /**
     * 动画移除view
     *
     * @param view
     */
    fun animRemoveView(view: View?, destroyPoint: Point) {
        if (view == null) {
            return
        }
        val x = view.x
        val y = view.y
        //计算直线距离
        val space = getDistance(Point(x.toInt(), y.toInt()), destroyPoint)
        val animator = ValueAnimator.ofFloat(x, 0f)
        /* ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view, "translationY", y, destroyPoint.y);*/
        //根据距离计算动画执行时间
        animator.duration = (REMOVE_DELAY_MILLIS / mMaxSpace * space).toLong()
        animator.interpolator = LinearInterpolator()
        animator.addUpdateListener(ValueAnimator.AnimatorUpdateListener { valueAnimator ->
            if (isCancelAnimtion) {
                return@AnimatorUpdateListener
            }
            val value = valueAnimator.animatedValue as Float
            val alpha = value / x
            //                float translationY = y + (x - value) * (maxY - y) / x;
            val translationY = y + (x - value) * (destroyPoint.y - y) / x
            //                setViewProperty(view, alpha, translationY, value);
            setViewProperty(view, alpha, translationY, x)
        })
        animator.addListener(object : AnimatorListenerAdapter() {
            override fun onAnimationEnd(animation: Animator) {
                //结束时从容器移除水滴
//                mViews.remove(view)
                removeView(view)
                if (null != mEndListener) {
                    mEndListener!!.endEnimator(view)
                }
            }
        })
        animator.start()
    }


    fun setAnimatorEndListener(endListener: AnimatorEndListener) {
        this.mEndListener = endListener
    }

    interface AnimatorEndListener {
        fun endEnimator(view: View?)
        fun finishAddView()
    }

    /**
     * 设置view的属性
     *
     * @param view
     * @param alpha
     * @param translationY
     * @param translationX
     */
    fun setViewProperty(view: View?, alpha: Float, translationY: Float, translationX: Float) {
        view!!.translationY = translationY
        view.translationX = translationX
        view.alpha = alpha
        view.scaleY = alpha
        view.scaleX = alpha
    }

    /**
     * 开启水滴抖动动画
     */
    private fun startAnimation() {
        /*   if (isOpenAnimtion) {
            return;
        }

        mHandler.sendEmptyMessage(WHAT_ADD_PROGRESS);
        isOpenAnimtion = true;*/
        setOffSet()
    }



    interface ClickListener {
        fun clickItem(view: View)
    }

    fun setOnItemClickListener(clickListener: ClickListener) {
        this.clickListener = clickListener
    }

    /**
     * 销毁
     */
    private fun onDestroy() {
        isCancelAnimtion = true
        if (mAnimation != null) {
            clearAnimation()
        }
        mHandler.removeCallbacksAndMessages(this)
    }

    companion object {
        private val WHAT_ADD_PROGRESS = 1
        /**
         * view变化的y抖动范围
         */
        private val CHANGE_RANGE = 10
        /**
         * 控制抖动动画执行的快慢，人眼不能识别16ms以下的
         */
        val PROGRESS_DELAY_MILLIS = 12
        /**
         * 控制移除view的动画执行时间
         */
        val REMOVE_DELAY_MILLIS = 2000
        /**
         * 添加水滴时动画显示view执行的时间
         */
        val ANIMATION_SHOW_VIEW_DURATION = 500
        /**
         * x最多可选取的随机数值
         */
        /*  private static final List<Float> X_MAX_CHOSE_RANDOMS = Arrays.asList(
            0.01f, 0.2f, 0.41f, 0.6f, 0.79f);
//    private static final List<Float> X_MAX_CHOSE_RANDOMS = new ArrayList<>();
    */
        /**
         * y最多可选取的随机数值
         */
        /* private static final List<Float> Y_MAX_CHOSE_RANDOMS = Arrays.asList(
            0.01f,0.38f, 0.35f, 0.69f);*/

        private val X_Y_CHOSE_RANDOMS = ArrayList<Position>()
    }
}
